﻿namespace Google.API.Predict.Auth
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// ClientLogin error message resolution
    /// </summary>
    public static class ClientLoginErrors
    {
        /// <summary>
        /// Provides error code specific messages
        /// </summary>
        private static readonly Dictionary<ClientLoginErrorCode, string> ErrorMessage = new Dictionary<ClientLoginErrorCode, string>
        {
            { ClientLoginErrorCode.AccountDeleted, "The user account has been deleted." },
            { ClientLoginErrorCode.AccountDisabled, "The user account has been disabled." },
            { ClientLoginErrorCode.BadAuthentication, "The login request used a username or password that is not recognized." },
            { ClientLoginErrorCode.CaptchaRequired, "A CAPTCHA is required. (A response with this error code will also contain an image URL and a CAPTCHA token.)" },
            { ClientLoginErrorCode.NoData, ".NET API Specific: Response contained no data." },
            { ClientLoginErrorCode.None, ".NET API Specific: 200 OK - No error" },
            { ClientLoginErrorCode.NotVerified, "The account email address has not been verified. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application." },
            { ClientLoginErrorCode.ServiceDisabled, "The user's access to the specified service has been disabled. (The user account may still be valid.)" },
            { ClientLoginErrorCode.ServiceUnavailable, "The service is not available; try again later." },
            { ClientLoginErrorCode.TermsNotAgreed, "The user has not agreed to terms. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application." },
            { ClientLoginErrorCode.Unknown, "The error is unknown or unspecified; the request contained invalid input or was malformed." },
        };

        /// <summary>
        /// Provides static dictionary for resolving strings to error codes
        /// </summary>
        private static readonly Dictionary<string, ClientLoginErrorCode> ErrorCode = new Dictionary<string, ClientLoginErrorCode>(StringComparer.OrdinalIgnoreCase)
        {
            { ClientLoginErrorCode.AccountDeleted.ToString(), ClientLoginErrorCode.AccountDeleted },
            { ClientLoginErrorCode.AccountDisabled.ToString(), ClientLoginErrorCode.AccountDisabled },
            { ClientLoginErrorCode.BadAuthentication.ToString(), ClientLoginErrorCode.BadAuthentication },
            { ClientLoginErrorCode.CaptchaRequired.ToString(), ClientLoginErrorCode.CaptchaRequired },
            { ClientLoginErrorCode.NoData.ToString(), ClientLoginErrorCode.NoData },
            { ClientLoginErrorCode.None.ToString(), ClientLoginErrorCode.None },
            { ClientLoginErrorCode.NotVerified.ToString(), ClientLoginErrorCode.NotVerified },
            { ClientLoginErrorCode.ServiceDisabled.ToString(), ClientLoginErrorCode.ServiceDisabled },
            { ClientLoginErrorCode.ServiceUnavailable.ToString(), ClientLoginErrorCode.ServiceUnavailable },
            { ClientLoginErrorCode.TermsNotAgreed.ToString(), ClientLoginErrorCode.TermsNotAgreed },
            { ClientLoginErrorCode.Unknown.ToString(), ClientLoginErrorCode.Unknown },
        };

        /// <summary>
        /// Resolves error strings to their corresponding error code
        /// </summary>
        /// <param name="error">error string to resolve</param>
        /// <returns>Resolved error code, ClientLoginErrorCode.None if null/empty, ClientLoginErrorCode.Unknown if not defined</returns>
        internal static ClientLoginErrorCode ResolveErrorCode(string error)
        {
            // Handle special case
            if (string.IsNullOrEmpty(error))
            {
                return ClientLoginErrorCode.None;
            }

            return ErrorCode.ContainsKey(error) ? ErrorCode[error] : ClientLoginErrorCode.Unknown;
        }

        /// <summary>
        /// Resolves error codes to their corresponding error message
        /// </summary>
        /// <param name="code">Code to resolve to an error message</param>
        /// <returns>Error message</returns>
        internal static string ResolveErrorMessage(ClientLoginErrorCode code)
        {
            return ErrorMessage.ContainsKey(code) ? ErrorMessage[code] : ErrorMessage[ClientLoginErrorCode.Unknown];
        }
    }
}
